#Android Databinding library
Explore tagged Tumblr posts
Text
Why you should consider ANDROID X migration?
Having trouble fixing your support library version? Not anymore! AndroidX is now available to resolve your issue.
What s AndroidX?
Along with Android Jetpack, an open-source project called AndroidX is presented.
In essence, it represents a significant upgrade over the original Android Support Library.
AndroidX, like the Support Library, ships independently of the Android OS and offers backward compatibility between different Android releases.
The older support libraries up to version 28 will continue to be made available in their current form, but newer versions of the libraries will be made available starting with version 1.0.0 of the AndroidX package overhaul.
Why you should migrate your app to Android X?
The life of the Android Support Library has ended. The Android Support namespace has not been updated since its final release, which was version 28.0. So, you must switch to Android X if you want bug patches or new features.
Other libraries, such as Google Play services, Firebase, Butterknife, Databinding Mockito, and SQL Delight, have switched to using the AndroidX namespace libraries.
The AndroidX namespace will be used for the release of all new Jetpack libraries. You must switch to the AndroidX namespace in outilize utilise features like Jetpack Compose or CameraX, for instance.
The Jetpack Navigation Component must adhere to Google’s recommendations. Simple Single-Activity Architecture App Approach.
Better package management: AndroidX offers independent, standardised versioning, better name standards, and more regular releases. Other libraries, such as Google Play services, Firebase, Butterknife, Databinding Mockito, and SQL Delight, have switched to using the AndroidX namespace libraries.
Migration is required: The AndroidX namespace will be used for the release of all new Jetpack libraries. You must switch to the AndroidX namespace in order to utilise features like Jetpack Compose or CameraX, for instance.
Simple App Architecture: Adopting Google’s suggested Single-Activity App Architecture requires the use of the Jetpack Navigation Component.
Google suggested using Arch Components and the MVVM paradigm with repos. To make the code base scalable, maintainable, and to get better CC, it is inevitable to create big-scale programmes using a modular architecture to isolate via modules.
CONCLUSION:
Upgrade to Android X effortlessly with BirajTech. If you’re seeking a seamless transition of your current Android app to Android X, BirajTech Services is your ideal choice. As a pioneering software company, we specialize in delivering top-tier mobile and web solutions for all your needs.
#web design#web developers#web development#web developing company#android#app migration#app design#birajtech
0 notes
Link

#android testing support library#Android apps creation#Android Databinding library#Android App Development
0 notes
Text
What is AndroidX and Why It is Important to Migrate to AndroidX
If you're unfamiliar with the phrase, AndroidX is a brand-new open-source initiative that Google is introducing to package libraries with Jetpack. In short, Google decided to start cleaning up their act and utilise a new approach along with new library names because the old method of managing libraries was becoming difficult.
AndroidX Overview
The Android team leverages the new open-source project called AndroidX to create, test, and distribute libraries for Jetpack.
A significant improvement over the original Android Support Library is AndroidX. Similar to the Support Library, AndroidX is developed separately from the Android OS and offers backward compatibility between different Android releases. By offering feature parity and additional libraries, AndroidX completely replaces the Support Library. Additionally, AndroidX has the following capabilities:
All AndroidX packages are located in a single namespace that begins with the letters android x. The comparable AndroidX.* packages have been mapped to the Support Library packages. See the Package Refactoring page for a complete mapping of all the old classes and build objects to the new ones.
Why migrate to AndroidX?
The support library is no longer being maintained and is now at version 28.0.0. Therefore, moving to AndroidX is crucial and necessary if we want bug fixes or new features that would previously have been included in the Support Library. The AndroidX namespace will be used for the release of all new Jetpack libraries.
There are a lot of benefits to switching from Android Support Library to AndroidX. The most recent version information is below:
Android 10 (API level 29)*
August 3, 2020: Required for new apps
November 2, 2020: Required for app updates
Better package management:
You get better consistent naming, more regular releases, and independent yet standardised versioning with AndroidX. Other libraries, such as Google Play services, Firebase, Butterknife, Databinding Mockito, and SQL Delight, have switched to using the AndroidX namespace libraries..
Migration is mandatory:
The AndroidX namespace will be used for the release of all new Jetpack libraries. You must switch to the AndroidX namespace in order to utilise features like Jetpack Compose or CameraX, for instance.
Hassle-free App Architecture:
If you want to create an app using Google's Single-Activity Architecture recommendation, you must use the Jetpack Navigation Component.
Google recommended arch:
MVVM pattern combined with Repos and Arch Components. To make the code base scalable, maintainable, and to get better CC, it is inevitable to create big scale programmes using a modular architecture to isolate via modules. Writing exams is made simple.
Conclusion:
There is no getting around this migration because the support library artefacts are being deprecated and all future development is moving to AndroidX. XcelTec is the best option if you want to transfer an existing Android app to Android X. We are a software company that has long offered the top mobile and web solutions.
Little about XcelTec:
To fulfil its purpose of "Delivering Excellence in Technology," XcelTec consistently transforms customer needs into innovative and worthwhile solutions.
We are a tech company that offers business solutions for offshore software development and software outsourcing. Microsoft technology, E-commerce, M-commerce, mobile development, and open source technology are all areas where XcelTec thrives.
By establishing a foundation of work ethics and continuous progress, we uphold honesty, the degree of fulfilment, and dependability with our deeply valued consumers. We can confidently and with great pride say that we are moving in the direction of our mission.
At our company, we are well aware that consumers are looking for employees that can fully understand their problems and logically provide clever digital solutions. XcelTec is aware that our customer wants to make things simple for everyone, whether it be their end customers, vendors, associates, or workers.
Sources:
Migrating to AndroidX: The time is right! Let’s summarize it!
AndroidX Support in React Native Apps
Visit to explore more on What is AndroidX and Why It is Important to Migrate to AndroidX
Get in touch with us for more!
Contact us on:- +91 987 979 9459 | +1 919 400 9200
Email us at:- [email protected]
#Mobile app development#androidx migration developer#androidx#web and mobile app development#Mobile app solution
1 note
·
View note
Photo

Android Jetpack: Replace findViewById with view binding The new view binding library allows yo... #surnativa #android #androiddevelopers #androiddevs #androidjetpack #app #appdevelopment #application #apps #code #concisecode #databinding #dev #develop #foundation #gdsyes #google #java #jetpack #kotlin #objcode #replacefindviewbyid #replacefindviewbyidwithviewbinding #safecode #seanmcquillan #ui #userexperience #userinterface #ux #viewbinding #viewbindingguide #viewbindinglibrary Source: https://surnativa.com/android-jetpack-replace-findviewbyid-with-view-binding/?feed_id=6394&_unique_id=5f29ec73df58d
0 notes
Text
android codelab 에서 예시로 보여주는 kotlin development
2.4 data bindings
original source: https://codelabs.developers.google.com/codelabs/kotlin-android-training-data-binding-basics/index.html?index=..%2F..android-kotlin-fundamentals#5
Steps to use data binding to replace calls to findViewById():
Enable data binding in the android section of the build.gradle file: dataBinding { enabled = true }
Use <layout> as the root view in your XML layout.
Define a binding variable: private lateinit var binding: ActivityMainBinding
Create a binding object in MainActivity, replacing setContentView: binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
Replace calls to findViewById() with references to the view in the binding object. For example: findViewById<Button>(R.id.done_button) ⇒ binding.doneButton (In the example, the name of the view is generated camel case from the view's id in the XML.)
Steps for binding views to data:
Create a data class for your data.
Add a <data> block inside the <layout> tag.
Define a <variable> with a name, and a type that is the data class.
<data> <variable name="myName" type="com.example.android.aboutme.MyName" /> </data>
In MainActivity, create a variable with an instance of the data class. For example: private val myName: MyName = MyName("Aleks Haecky")
In the binding object, set the variable to the variable you just created: binding.myName = myName
In the XML, set the content of the view to the variable that you defined in the <data> block. Use dot notation to access the data inside the data class. android:text="@={myName.name}"
.
.
.
.
3.1 fragment
https://codelabs.developers.google.com/codelabs/kotlin-android-training-create-and-add-fragment/index.html?index=..%2F..android-kotlin-fundamentals#3
.
.
.
.
3.2 Navigation components
original source : https://codelabs.developers.google.com/codelabs/kotlin-android-training-add-navigation/index.html?index=..%2F..android-kotlin-fundamentals#0
To use the Android navigation library, you need to do some setup:
Add dependencies for navigation-fragment-ktx and navigation-ui-ktx in the module-level build.gradle file.
Add an ext variable for the navigationVersion in the project-level build.gradle file.
Navigation destinations are fragments, activities, or other app components that the user navigates to. A navigation graph defines the possible paths from one navigation destination to the next.
To create a navigation graph, create a new Android resource file of type Navigation. This file defines the navigation flow through the app. The file is in the res/navigation folder, and it's typically called navigation.xml.
To see the navigation graph in the Navigation Editor, open the navigation.xml file and click the Design tab.
Use the Navigation Editor to add destinations such as fragments to the navigation graph.
To define the path from one destination to another, use the Navigation Graph to create an action that connects the destinations. In the navigation.xml file, each of these connections is represented as an action that has an ID.
A navigation host fragment, usually named NavHostFragment, acts as a host for the fragments in the navigation graph:
As the user moves between destinations defined in the navigation graph, the NavHostFragment swaps the fragments in and out and manages the fragment back stack.
In the activity_main.xml layout file, the NavHostFragment is represented by a fragment element with the name android:name="androidx.navigation.fragment.NavHostFragment".
To define which fragment is displayed when the user taps a view (for example a button), set the onClick listener for the view:
In the onClick listener, call findNavController().navigate() on the view.
Specify the ID of the action that leads to the destination.
Conditional navigation navigates to one screen in one case, and to a different screen in another case. To create conditional navigation:
Use the Navigation Editor to create a connection from the starting fragment to each of the possible destination fragments.
Give each connection a unique ID.
In the click-listener method for the View, add code to detect the conditions. Then call findNavController().navigate() on the view, passing in the ID for the appropriate action.
참고자료) popup popupto PopUpToInclusive 설명 10분분량 매우 간결하다.
https://youtu.be/mLfWvSGG5c8
The Back button
The system's Back button is usually at the bottom of the device. By default, the Back button navigates the user back to the screen they viewed most recently. In some situations, you can control where the Back button takes the user:
In the Navigation Editor, you can use the Attributes pane to change an action's Pop To setting. This setting removes destinations from the back stack, which has the effect of determining where the Back button takes the user.
The Pop To setting appears as the popUpTo attribute in the navigation.xml file.
Selecting the Inclusive checkbox sets the popUpToInclusive attribute to true. All destinations up to and including this destination are removed from the back stack.
If an action's popUpTo attribute is set to the app's the starting destination and popUpToInclusive is set to true, the Back button takes the user all the way out of the app.
The Up button
Screens in an Android app can have an on-screen Up button that appears at the top left of the app bar. (The app bar is sometimes called the action bar.) The Up button navigates "upwards" within the app's screens, based on the hierarchical relationships between screens.
The navigation controller's NavigationUI library integrates with the app bar to allow the user to tap the Up button on the app bar to get back to the app's home screen from anywhere in the app.
To link the navigation controller to the app bar:
In onCreate(), call setupActionBarWithNavController() on the NavigationUI class, passing in the navigation controller:
val navController = this.findNavController(R.id.myNavHostFragment) NavigationUI.setupActionBarWithNavController(this,navController)
Override the onSupportNavigateUp() method to call navigateUp() in the navigation controller:
override fun onSupportNavigateUp(): Boolean { val navController = this.findNavController(R.id.myNavHostFragment) return navController.navigateUp() } }
The options menu
The options menu is a menu that the user accesses from the app bar by tapping the icon with the three vertical dots . To create an options menu with a menu item that displays a fragment, make sure the fragment has an ID. Then define the options menu and code the onOptionsItemSelected() handler for the menu items.
1. Make sure the fragment has an ID:
Add the destination fragment to the navigation graph and note the ID of the fragment. (You can change the ID if you like.)
2. Define the options menu:
Create an Android resource file of type Menu, typically named options_menu.xml. The file is stored in the Res > Menu folder.
Open the options_menu.xml file in the design editor and drag a Menu Item widget from the Palette pane to the menu.
For convenience, make the ID of the menu item the same as the ID of the fragment to display when the user clicks this menu item. This step is not required, but it makes it easier to code the onClick behavior for the menu item.
3. Code the onClick handler for the menu item:
In the fragment or activity that displays the options menu, in onCreateView(), call setHasOptionsMenu(true) to enable the options menu.
Implement onCreateOptionsMenu() to inflate the options menu:
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) { super.onCreateOptionsMenu(menu, inflater) inflater?.inflate(R.menu.options_menu, menu) }
Override the onOptionsItemSelected() method to take the appropriate action when the menu item is clicked. The following code displays the fragment that has the same ID as the menu item. (This code only works if the menu item and the fragment have identical ID values.)
override fun onOptionsItemSelected(item: MenuItem?): Boolean { return NavigationUI.onNavDestinationSelected(item!!, view!!.findNavController()) || super.onOptionsItemSelected(item) }
The navigation drawer
The navigation drawer is a panel that slides out from the edge of the screen. There are two ways for the user to open the navigation drawer:
Swipe from the starting edge (usually the left) on any screen.
Use the drawer button (three lines) on the app bar at the top of the app.
To add a navigation drawer to your app:
Add dependencies to build.gradle (app).
Make sure each destination fragment has an ID.
Create the menu for the drawer.
Add the drawer to the layout for the fragment.
Connect the drawer to the navigation controller.
Set up the drawer button in the app bar.
These steps are explained in more detail below.
1. Add dependencies to build.gradle:
The navigation drawer is part of the Material Components for Android library. Add the Material library to the build.gradle (app) file:
dependencies { ... implementation "com.google.android.material:material:$supportlibVersion" ... }
2. Give each destination fragment an ID:
If a fragment is reachable from the navigation drawer, open it in the navigation graph to make sure that it has an ID.
3. Create the menu for the drawer:
Create an Android resource file of type Menu (typically called navdrawer_menu) for a navigation drawer menu. This creates a new navdrawer_menu.xml file in the Res > Menu folder.
In the design editor, add Menu Item widgets to the Menu.
4. Add the drawer to the layout for the fragment:
In the layout that contains the navigation host fragment (which is typically the main layout), use <androidx.drawerlayout.widget.DrawerLayout> as the root view.
Add a <com.google.android.material.navigation.NavigationView> view to the layout.
5. Connect the drawer to the navigation controller:
Open the activity that creates the navigation controller. (The main activity is typically the one you want here.) In onCreate(), use NavigationUI.setupWithNavController()to connect the navigation drawer with the navigation controller:
val binding = DataBindingUtil.setContentView<ActivityMainBinding>( this, R.layout.activity_main) NavigationUI.setupWithNavController(binding.navView, navController)
6. Set up the drawer button in the app bar:
In onCreate() in the activity that creates the navigation controller (which is typically the main activity), pass the drawer layout as the third parameter to NavigationUI.setupActionBarWithNavController:
val binding = DataBindingUtil.setContentView<ActivityMainBinding>( this, R.layout.activity_main) NavigationUI.setupActionBarWithNavController( this, navController, binding.drawerLayout)
To make the Up button work with the drawer button, edit onSupportNavigateUp() to return NavigationUI.navigateUp(). Pass the navigation controller and the drawer layout to navigateUp().
override fun onSupportNavigateUp(): Boolean { val navController = this.findNavController(R.id.myNavHostFragment) return NavigationUI.navigateUp(navController, drawerLayout) }
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-start-external-activity/index.html?index=..%2F..android-kotlin-fundamentals#0
3.3
Safe Args navigation pass arguments fragment NavDirection
https://codelabs.developers.google.com/codelabs/kotlin-android-training-start-external-activity/index.html?index=..%2F..android-kotlin-fundamentals#2
내가 헷갈렸던 내용) navigation을 이용한 fragment간의 이동시 action을 통해 이동한다. 이때 args를 전달할수 있는데 그 arg는 아래와 같이 action이름.arg이름 형태로 접근 할수 있다. navigation xml화일을 보면 <action> 안에 <argument>를 가지고 있는 것을 볼수 있다.
<fragment android:id="@+id/myFragment" > <argument android:name="myArg" app:argType="integer" android:defaultValue="0" /> </fragment>
.
..
.
.
4.1 Lifecycle onSaveInstanceState Bundle
https://codelabs.developers.google.com/codelabs/kotlin-android-training-complex-lifecycle/index.html?index=..%2F..android-kotlin-fundamentals#2
Lifecycle tips
If you set up or start something in a lifecycle callback, stop or remove that thing in the corresponding callback. By stopping the thing, you make sure it doesn't keep running when it's no longer needed. For example, if you set up a timer in onStart(), you need to pause or stop the timer in onStop().
Use onCreate() only to initialize the parts of your app that run once, when the app first starts. Use onStart() to start the parts of your app that run both when the app starts, and each time the app returns to the foreground.
Lifecycle library
Use the Android lifecycle library to shift lifecycle control from the activity or fragment to the actual component that needs to be lifecycle-aware.
Lifecycle owners are components that have (and thus "own") lifecycles, including Activity and Fragment. Lifecycle owners implement the LifecycleOwner interface.
Lifecycle observers pay attention to the current lifecycle state and perform tasks when the lifecycle changes. Lifecycle observers implement the LifecycleObserver interface.
Lifecycle objects contain the actual lifecycle states, and they trigger events when the lifecycle changes.
To create a lifecycle-aware class:
Implement the LifecycleObserver interface in classes that need to be lifecycle-aware.
Initialize a lifecycle observer class with the lifecycle object from the activity or fragment.
In the lifecycle observer class, annotate lifecycle-aware methods with the lifecycle state change they are interested in. For example, the @OnLifecycleEvent(Lifecycle.Event.ON_START)annotation indicates that the method is watching the onStart lifecycle event.
Process shutdowns and saving activity state
Android regulates apps running in the background so that the foreground app can run without problems. This regulation includes limiting the amount of processing that apps in the background can do, and sometimes even shutting down your entire app process.
The user cannot tell if the system has shut down an app in the background. The app still appears in the recents screen and should restart in the same state in which the user left it.
The Android Debug Bridge (adb) is a command-line tool that lets you send instructions to emulators and devices attached to your computer. You can use adb to simulate a process shutdown in your app.
When Android shuts down your app process, the onDestroy() lifecycle method is not called. The app just stops.
Preserving activity and fragment state
When your app goes into the background, just after onStop() is called, app data is saved to a bundle. Some app data, such as the contents of an EditText, is automatically saved for you.
The bundle is an instance of Bundle, which is a collection of keys and values. The keys are always strings.
Use the onSaveInstanceState() callback to save other data to the bundle that you want to retain, even if the app was automatically shut down. To put data into the bundle, use the bundle methods that start with put, such as putInt().
You can get data back out of the bundle in the onRestoreInstanceState() method, or more commonly in onCreate(). The onCreate() method has a savedInstanceState parameter that holds the bundle.
If the savedInstanceState variable contains null, the activity was started without a state bundle and there is no state data to retrieve.
To retrieve data from the bundle with a key, use the Bundle methods that start with get, such as getInt().
Configuration changes
A configuration change happens when the state of the device changes so radically that the easiest way for the system to resolve the change is to shut down and rebuild the activity.
The most common example of a configuration change is when the user rotates the device from portrait to landscape mode, or from landscape to portrait mode. A configuration change can also occur when the device language changes or a hardware keyboard is plugged in.
When a configuration change occurs, Android invokes all the activity lifecycle's shutdown callbacks. Then Android restarts the activity from scratch, running all the lifecycle startup callbacks.
When Android shuts down an app because of a configuration change, it restarts the activity with the state bundle that is available to onCreate().
As with process shutdown, save your app's state to the bundle in onSaveInstanceState().
.
.
.
.
5.1 view model factory provider에 대한 참고사항
어떤 방법이 옳고 어떻게 해야 boiler plate code를 줄일수 있는지 설명한다.
https://proandroiddev.com/view-model-creation-in-android-android-architecture-components-kotlin-ce9f6b93a46b
.
.
.
.
https://developer.android.com/topic/libraries/architecture/viewmodel
ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-live-data/index.html?index=..%2F..android-kotlin-fundamentals#10
5.2 LiveData
LiveData is an observable data holder class that is lifecycle-aware, one of the Android Architecture Components.
You can use LiveData to enable your UI to update automatically when the data updates.
LiveData is observable, which means that an observer like an activity or an fragment can be notified when the data held by the LiveData object changes.
LiveData holds data; it is a wrapper that can be used with any data.
LiveData is lifecycle-aware, meaning that it only updates observers that are in an active lifecycle state such as STARTED or RESUMED.
To add LiveData
Change the type of the data variables in ViewModel to LiveData or MutableLiveData.
MutableLiveData is a LiveData object whose value can be changed. MutableLiveData is a generic class, so you need to specify the type of data that it holds.
To change the value of the data held by the LiveData, use the setValue() method on the LiveData variable.
To encapsulate LiveData
The LiveData inside the ViewModel should be editable. Outside the ViewModel, the LiveData should be readable. This can be implemented using a Kotlin backing property.
A Kotlin backing property allows you to return something from a getter other than the exact object.
To encapsulate the LiveData, use private MutableLiveData inside the ViewModel and return a LiveData backing property outside the ViewModel.
Observable LiveData
LiveData follows an observer pattern. The "observable" is the LiveData object, and the observers are the methods in the UI controllers, like fragments. Whenever the data wrapped inside LiveData changes, the observer methods in the UI controllers are notified.
To make the LiveData observable, attach an observer object to the LiveData reference in the observers (such as activities and fragments) using the observe() method.
This LiveData observer pattern can be used to communicate from the ViewModel to the UI controllers.
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-live-data-data-binding/index.html?index=..%2F..android-kotlin-fundamentals#6
5.3 Data binding and LiveData
Summary
The Data Binding Library works seamlessly with Android Architecture Components like ViewModel and LiveData.
The layouts in your app can bind to the data in the Architecture Components, which already help you manage the UI controller's lifecycle and notify about changes in the data.
ViewModel data binding
You can associate a ViewModel with a layout by using data binding.
ViewModel objects hold the UI data. By passing ViewModel objects into the data binding, you can automate some of the communication between the views and the ViewModel objects.
How to associate a ViewModel with a layout:
In the layout file, add a data-binding variable of the type ViewModel.
<data> <variable name="gameViewModel" type="com.example.android.guesstheword.screens.game.GameViewModel" /> </data>
In the GameFragment file, pass the GameViewModel into the data binding.
binding.gameViewModel = viewModel
Listener bindings
Listener bindings are binding expressions in the layout that run when click events such as onClick() are triggered.
Listener bindings are written as lambda expressions.
Using listener bindings, you replace the click listeners in the UI controllers with listener bindings in the layout file.
Data binding creates a listener and sets the listener on the view.
android:onClick="@{() -> gameViewModel.onSkip()}"
Adding LiveData to data binding
LiveData objects can be used as a data-binding source to automatically notify the UI about changes in the data.
You can bind the view directly to the LiveData object in the ViewModel. When the LiveData in the ViewModel changes, the views in the layout can be automatically updated, without the observer methods in the UI controllers.
android:text="@{gameViewModel.word}"
To make the LiveData data binding work, set the current activity (the UI controller) as the lifecycle owner of the binding variable in the UI controller.
binding.lifecycleOwner = this
String formatting with data binding
Using data binding, you can format a string resource with placeholders like %s for strings and %d for integers.
To update the text attribute of the view, pass in the LiveData object as an argument to the formatting string.
android:text="@{@string/quote_format(gameViewModel.word)}"
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-live-data-transformations/index.html?index=..%2F..android-kotlin-fundamentals#7
livedata를 일반 data를 wrapper로 감싼 형태 가정하고 그안의 내용만을 수정한 livedata를 얻고자 하는 경우 Transformations를 이용해서 내용을 변경할수 있다.
5.4 LiveData and Transformations
Transforming LiveData
Sometimes you want to transform the results of LiveData. For example, you might want to format a Date string as "hours:mins:seconds," or return the number of items in a list rather than returning the list itself. To perform transformations on LiveData, use helper methods in the Transformations class.
The Transformations.map() method provides an easy way to perform data manipulations on the LiveData and return another LiveData object. The recommended practice is to put data-formatting logic that uses the Transformations class in the ViewModel along with the UI data.
Displaying the result of a transformation in a TextView
Make sure the source data is defined as LiveData in the ViewModel.
Define a variable, for example newResult. Use Transformation.map() to perform the transformation and return the result to the variable.
val newResult = Transformations.map(someLiveData) { input -> // Do some transformation on the input live data // and return the new value }
Make sure the layout file that contains the TextView declares a <data> variable for the ViewModel.
<data> <variable name="MyViewModel" type="com.example.android.something.MyViewModel" /> </data>
In the layout file, set the text attribute of the TextView to the binding of the newResult of the ViewModel. For example:
android:text="@{SomeViewModel.newResult}"
Formatting dates
The DateUtils.formatElapsedTime() utility method takes a long number of milliseconds and formats the number to use a MM:SS string format.
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-room-database/index.html?index=..%2F..android-kotlin-fundamentals#8
6.1 Room
참고자료) official docs
https://developer.android.com/training/data-storage/room/accessing-data
Define your tables as data classes annotated with @Entity. Define properties annotated with @ColumnInfo as columns in the tables.
Define a data access object (DAO) as an interface annotated with @Dao. The DAO maps Kotlin functions to database queries.
Use annotations to define @Insert, @Delete, and @Update functions.
Use the @Query annotation with an SQLite query string as a parameter for any other queries.
Create an abstract class that has a getInstance() function that returns a database.
Use instrumented tests to test that your database and DAO are working as expected. You can use the provided tests as a template.
.
.
.
.
일반적으로 Coroutines를 이용한 database작업의 패턴
https://codelabs.developers.google.com/codelabs/kotlin-android-training-coroutines-and-room/index.html?index=..%2F..android-kotlin-fundamentals#5
Launch a coroutine that runs on the main or UI thread, because the result affects the UI.
Call a suspend function to do the long-running work, so that you don't block the UI thread while waiting for the result.
The long-running work has nothing to do with the UI. Switch to the I/O context, so that the work can run in a thread pool that's optimized and set aside for these kinds of operations.
Then call the database function to do the work.
The pattern is shown below.
fun someWorkNeedsToBeDone { uiScope.launch { suspendFunction() } } suspend fun suspendFunction() { withContext(Dispatchers.IO) { longrunningWork() } }
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-coroutines-and-room/index.html?index=..%2F..android-kotlin-fundamentals#7
6.2 Corouitnes과 room database, LiveData
Use ViewModel, ViewModelFactory, and data binding to set up the UI architecture for the app.
To keep the UI running smoothly, use coroutines for long-running tasks, such as all database operations.
Coroutines are asynchronous and non-blocking. They use suspend functions to make asynchronous code sequential.
When a coroutine calls a function marked with suspend, instead of blocking until that function returns like a normal function call, it suspends execution until the result is ready. Then it resumes where it left off with the result.
The difference between blocking and suspending is that if a thread is blocked, no other work happens. If the thread is suspended, other work happens until the result is available.
To launch a coroutine, you need a job, a dispatcher, and a scope:
Basically, a job is anything that can be canceled. Every coroutine has a job, and you can use a job to cancel a coroutine.
The dispatcher sends off coroutines to run on various threads. Dispatcher.Main runs tasks on the main thread, and Dispartcher.IO is for offloading blocking I/O tasks to a shared pool of threads.
The scope combines information, including a job and dispatcher, to define the context in which the coroutine runs. Scopes keep track of coroutines.
To implement click handlers that trigger database operations, follow this pattern:
Launch a coroutine that runs on the main or UI thread, because the result affects the UI.
Call a suspend function to do the long-running work, so that you don't block the UI thread while waiting for the result.
The long-running work has nothing to do with the UI, so switch to the I/O context. That way, the work can run in a thread pool that's optimized and set aside for these kinds of operations.
Then call the database function to do the work.
Use a Transformations map to create a string from a LiveData object every time the object changes.
.
.
.
.
6.3 LiveData 와 control buttons
https://codelabs.developers.google.com/codelabs/kotlin-android-training-quality-and-states/index.html?index=..%2F..android-kotlin-fundamentals#6
Create a ViewModel and a ViewModelFactory and set up a data source.
Trigger navigation. To separate concerns, put the click handler in the view model and the navigation in the fragment.
Use encapsulation with LiveData to track and respond to state changes.
Use transformations with LiveData.
Create a singleton database.
Set up coroutines for database operations.
Triggering navigation
You define possible navigation paths between fragments in a navigation file. There are some different ways to trigger navigation from one fragment to the next. These include:
Define onClick handlers to trigger navigation to a destination fragment.
Alternatively, to enable navigation from one fragment to the next:
Define a LiveData value to record if navigation should occur.
Attach an observer to that LiveData value.
Your code then changes that value whenever navigation needs to be triggered or is complete.
Setting the android:enabled attribute
The android:enabled attribute is defined in TextView and inherited by all subclasses, including Button.
The android:enabled attribute determines whether or not a View is enabled. The meaning of "enabled" varies by subclass. For example, a non-enabled EditText prevents the user from editing the contained text, and a non-enabled Button prevents the user from tapping the button.
The enabled attribute is not the same as the visibility attribute.
You can use transformation maps to set the value of the enabled attribute of buttons based on the state of another object or variable.
Other points covered in this codelab:
To trigger notifications to the user, you can use the same technique as you use to trigger navigation.
You can use a Snackbar to notify the user.
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-recyclerview-fundamentals/index.html?index=..%2F..android-kotlin-fundamentals#7
7.1 recyclerView
Displaying a list or grid of data is one of the most common UI tasks in Android. RecyclerView is designed to be efficient even when displaying extremely large lists.
RecyclerView does only the work necessary to process or draw items that are currently visible on the screen.
When an item scrolls off the screen, its views are recycled. That means the item is filled with new content that scrolls onto the screen.
The adapter pattern in software engineering helps an object work together with another API. RecyclerView uses an adapter to transform app data into something it can display, without the need for changing how the app stores and processes data.
To display your data in a RecyclerView, you need the following parts:
RecyclerView To create an instance of RecyclerView, define a <RecyclerView> element in the layout file.
LayoutManager A RecyclerView uses a LayoutManager to organize the layout of the items in the RecyclerView, such as laying them out in a grid or in a linear list. In the <RecyclerView> in the layout file, set the app:layoutManager attribute to the layout manager (such as LinearLayoutManager or GridLayoutManager). You can also set the LayoutManager for a RecyclerView programmatically. (This technique is covered in a later codelab.)
Layout for each item Create a layout for one item of data in an XML layout file.
Adapter Create an adapter that prepares the data and how it will be displayed in a ViewHolder. Associate the adapter with the RecyclerView. When RecyclerView runs, it will use the adapter to figure out how to display the data on the screen. The adapter requires you to implement the following methods: – getItemCount() to return the number of items. – onCreateViewHolder() to return the ViewHolder for an item in the list. – onBindViewHolder() to adapt the data to the views for an item in the list.
ViewHolder A ViewHolder contains the view information for displaying one item from the item's layout.
The onBindViewHolder() method in the adapter adapts the data to the views. You always override this method. Typically, onBindViewHolder() inflates the layout for an item, and puts the data in the views in the layout.
Because the RecyclerView knows nothing about the data, the Adapter needs to inform the RecyclerView when that data changes. Use notifyDataSetChanged()to notify the Adapter that the data has changed.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-recyclerview-fundamentals/index.html?index=..%2F..android-kotlin-fundamentals#5
refactor refactoring
특정코드 외부로 extract 해서 새로 function만들기
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-diffutil-databinding/index.html?index=..%2F..android-kotlin-fundamentals#2
7.2 DiffUtil , data binding, ListAdapter
https://codelabs.developers.google.com/codelabs/kotlin-android-training-diffutil-databinding/index.html?index=..%2F..android-kotlin-fundamentals#3
DiffUtil의 사용예시 (ListAdapter에서 변경된 data에 해당하는 viewholder만 변경해서 효율을 높이기 위해 사용된다. 어떤 data가 변경된 것인지 확인하는 역할을 한다.)
https://codelabs.developers.google.com/codelabs/kotlin-android-training-diffutil-databinding/index.html?index=..%2F..android-kotlin-fundamentals#4
ListAdapter 사용 예시.
ListAdapter를 RecyclerView 사용하면 몇몇 편해지는 부분이 있다. getItemCount()를 구현하지 않아도 된다. 보여줄 data list를 adapter에 전달할때는 adapter.submitList(it)를 이용한다. adapter안에 data list를 저장할 variable을 만들 필요가 없다.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-diffutil-databinding/index.html?index=..%2F..android-kotlin-fundamentals#5
data binding 과 recycler view를 같이 사용하는 예시
refactor refactoring 하는 예시 몇개 있음
https://codelabs.developers.google.com/codelabs/kotlin-android-training-diffutil-databinding/index.html?index=..%2F..android-kotlin-fundamentals#6
data binding 과 recycler view를 같이 사용하는 예시
DiffUtil:
RecyclerView has a class called DiffUtil which is for calculating the differences between two lists.
DiffUtil has a class called ItemCallBack that you extend in order to figure out the difference between two lists.
In the ItemCallback class, you must override the areItemsTheSame() and areContentsTheSame() methods.
ListAdapter:
To get some list management for free, you can use the ListAdapter class instead of RecyclerView.Adapter. However, if you use ListAdapter you have to write your own adapter for other layouts, which is why this codelab shows you how to do it.
To open the intention menu in Android Studio, place the cursor on any item of code and press Alt+Enter (Option+Enter on a Mac). This menu is particularly helpful for refactoring code and creating stubs for implementing methods. The menu is context-sensitive, so you need to place cursor exactly to get the correct menu.
Data binding:
Use data binding in the item layout to bind data to the views.
Binding adapters:
You previously used Transformations to create strings from data. If you need to bind data of different or complex types, provide binding adapters to help data binding use them.
To declare a binding adapter, define a method that takes an item and a view, and annotate the method with @BindingAdapter. In Kotlin, you can write the binding adapter as an extension function on the View. Pass in the name of the property that the adapter adapts. For example:
@BindingAdapter("sleepDurationFormatted")
In the XML layout, set an app property with the same name as the binding adapter. Pass in a variable with the data. For example:
.app:sleepDurationFormatted="@{sleep}"
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-grid-layout/index.html?index=..%2F..android-kotlin-fundamentals#5
GridLayout and RecyclerView
Layout managers manage how the items in the RecyclerView are arranged.
RecyclerView comes with out-of-the-box layout managers for common use cases such as LinearLayout for horizontal and vertical lists, and GridLayout for grids.
For more complicated use cases, implement a custom LayoutManager.
From a design perspective, GridLayout is best used for lists of items that can be represented as icons or images.
GridLayout arranges items in a grid of rows and columns. Assuming vertical scrolling, each item in a row takes up what's called a "span."
You can customize how many spans an item takes up, creating more interesting grids without the need for a custom layout manager.
Create an item layout for one item in the grid, and the layout manager takes care of arranging the items.
You can set the LayoutManager for the RecyclerView either in the XML layout file that contains the <RecyclerView> element, or programmatically.
.
.
.
.
https://codelabs.developers.google.com/codelabs/kotlin-android-training-interacting-with-items/index.html?index=..%2F..android-kotlin-fundamentals#6
interaction with recyclerview
To make items in a RecyclerView respond to clicks, attach click listeners to list items in the ViewHolder, and handle clicks in the ViewModel.
To make items in a RecyclerView respond to clicks, you need to do the following:
Create a listener class that takes a lambda and assigns it to an onClick() function.
class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) { fun onClick(night: SleepNight) = clickListener(night.nightId) }
Set the click listener on the view.
android:onClick="@{() -> clickListener.onClick(sleep)}"
Pass the click listener to the adapter constructor, into the view holder, and add it to the binding object.
class SleepNightAdapter(val clickListener: SleepNightListener): ListAdapter<DataItem, RecyclerView.ViewHolder>(SleepNightDiffCallback()
holder.bind(getItem(position)!!, clickListener)
binding.clickListener = clickListener
In the fragment that shows the recycler view, where you create the adapter, define a click listener by passing a lambda to the adapter.
val adapter = SleepNightAdapter(SleepNightListener { nightId -> sleepTrackerViewModel.onSleepNightClicked(nightId) })
Implement the click handler in the view model. For clicks on list items, this commonly triggers navigation to a detail fragment.
.
.
package com.example.android.trackmysleepquality.sleeptracker import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.example.android.trackmysleepquality.database.SleepNight import com.example.android.trackmysleepquality.databinding.ListItemSleepNightBinding class SleepNightAdapter(val clickListener: SleepNightListener) : ListAdapter<SleepNight, SleepNightAdapter.ViewHolder>(SleepNightDiffCallback()) { override fun onBindViewHolder(holder: ViewHolder, position: Int) { holder.bind(getItem(position)!!, clickListener) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { return ViewHolder.from(parent) } class ViewHolder private constructor(val binding: ListItemSleepNightBinding) : RecyclerView.ViewHolder(binding.root){ fun bind(item: SleepNight, clickListener: SleepNightListener) { binding.sleep = item binding.clickListener = clickListener binding.executePendingBindings() } companion object { fun from(parent: ViewGroup): ViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val binding = ListItemSleepNightBinding.inflate(layoutInflater, parent, false) return ViewHolder(binding) } } } } class SleepNightDiffCallback : DiffUtil.ItemCallback<SleepNight>() { override fun areItemsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean { return oldItem.nightId == newItem.nightId } override fun areContentsTheSame(oldItem: SleepNight, newItem: SleepNight): Boolean { return oldItem == newItem } } class SleepNightListener(val clickListener: (sleepId: Long) -> Unit) { fun onClick(night: SleepNight) = clickListener(night.nightId) }
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="sleep" type="com.example.android.trackmysleepquality.database.SleepNight"/> <variable name="clickListener" type="com.example.android.trackmysleepquality.sleeptracker.SleepNightListener" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="@{() -> clickListener.onClick(sleep)}"> <ImageView android:id="@+id/quality_image" android:layout_width="@dimen/icon_size" android:layout_height="60dp" android:layout_marginStart="16dp" android:layout_marginTop="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:srcCompat="@drawable/ic_sleep_5" app:sleepImage="@{sleep}"/> <TextView android:id="@+id/quality_string" android:layout_width="0dp" android:layout_height="20dp" android:textAlignment="center" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/quality_image" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="@+id/quality_image" app:layout_constraintTop_toBottomOf="@+id/quality_image" tools:text="Excellent!!!" app:sleepQualityString="@{sleep}" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
0 notes
Text
KM Quick Adapter
You can easily crate RecyclerviewAdapter and PagedlistAdapter using databinding with this library.
from The Android Arsenal https://ift.tt/2CaELFY
0 notes
Link
Android databinding support library with the latest features, how to implement and use databinding in application. In this tutorial Android app development India is explained step by step full overview of Implement a databinding in Android with complete a example of display contacts numbers using recyclerview.
0 notes
Text
Preserve Meta-Characters during Replacement & Enhanced LINQ Reporting Engine inside Java Apps
What's New in this Release?
Aspose development team is happy to announce the monthly release of Aspose.Words for Java 18.1.0. There are 63 improvements and fixes in this regular monthly release. The most notable includes improved character spacing control logic, improved space shrinking for Verdana font, improved “allow handing punctuation” handling when kerning is enabled, Fixed clip issue with semi-broken tables, Fixed draw order of wrapped shapes in 2013 mode, Fixed repeated header height problem during field update, Fixed the bug causing error in page numbers in multi-page documents rendered into PostScript, Proper calculation of undocumented margins in DrawingML Charts implemented, Horizontal axis of Bubble Chart scaling fixed, Vertical axis of 3DArea Chart scaling fixed, MS Word 2016 approach for rendering of DrawingML Charts axis labels implemented; (Labels are rotated to fit the chart), Fixed rendering of Legend markers for 3D-LineChart, Improved rendering of composite (with multiple series) charts and Chart title with ManualLayout rendering fixed. This release has enhanced the support of data band inside a single-column table row for LINQ Reporting Engine. In previous versions of Aspose.Words, when opening and closing foreach tags are inside same cell, the output contents would be in the same cell. Starting from Aspose.Words 18.1, users can export the single-column data band in separate new row using greedy switch. This has enhanced the support of conditional blocks in table’s row for LINQ Reporting Engine. If users put an opening if, elseif, or else tag and a closing if tag in the same cell, the engine treats a template option formed by these tags as a common one rather than a table-row one by default. However, users can override this behavior making the engine to treat such a template option as a table-row one by specifying a greedy switch. It has added FindReplaceOptions.PreserveMetaCharacters property in Aspose.Words 18.1 to preserve meta-characters beginning with “&” during replacement. In this release, Aspose team has removed following obsolete public method from CompositeNode class. The parameter “isLive” is not used anymore. Please use CompositeNode.GetChildNodes(NodeType nodeType, bool isDeep) instead. It has added new feature in the release of Aspose.Words to show or hide the chart axis. You can use ChartAxis.Hidden property to achieve this. XmlMapping.StoreItemId property has been added in this release to specify the custom XML data identifier for the custom XML data part. Please read DataBinding class for more detail about storeItemID property. The list of new and improved features added in this release are given below
Add feature to show/hide axis of chart
API to get geometric position of element in Word Doc
Add feature to get w:storeItemID of StructuredDocumentTag
Add feature to add multiple replies to comment using Comment.AddReply
RTF to Pdf conversion issue with text-box position
Empty row gets added when closing tag <</foreach>> is in last row of table
Incorrect ChartDataPoint Cloning
Some headers/footers have height of 0 in XMLs obtained by internal layout API
Rework Pdf digital signing code to be compatible with NetStandart 2.0
The length of superscripted footnote's text is incorrect in RTF output.
Shape is not rendered correctly in output PDF
Cleen up System.Security.Cryptography.Xml.
Removed Aspose.Xamarin.Security project.
Gradient fill image is filled as solid fill in PDF
Thai words are showing as squares when converted to DOC.
Document.UpdateFields does not update LastSavedTime.
Bullets rendering issue on Linux
Header contents are overlapped with body contents after conversion from Docx to Pdf
Content overlaps footer
Right borders specified for "tr" or "tbody" elements are not applied to cell
ReplacingArgs.Replacement returns incorrect value
Scaling issue of charts in DOCX to PDF conversion
Difference in values of axis in DOCX to PDF rendering
Barcode images are missing upon RTF conversion
DOCX to PDF conversion loses some images
Font information garbled in RTF document
White Paragraphs in Cells Turn Black during Saving a RTF
Incorrect TOC page number in RTF to DOCX conversion
Incorrect TOC page number in RTF to DOCX conversion
System.NullReferenceException is thrown when RevisionOptions.ShowRevisionBalloons is set to true
Repeating Section Content Control is not rendered in output PDF
RTF to DOCX conversion issue for Footnote Words Become Superscript
Incorrect rotation of the X-axis label text when exporting to PDF
Legend markers for 3D-LineChart are rendered incorrectly when exporting to PDF
Incorrect TOC page number in RTF to DOCX conversion
Error in page number when converting to PostScript
Range.Replace text within GroupShape does not Replace
DOCX to HTML conversion issue with chart rendering
OfficeMath is changed after re-saving DOCX
AllowHangingPunctuation rule is improperly processed
When open DOCX file, an exception occurs
Html save as Odt - view of table is different than in Docx and in MS Word
Document.Compare returns incorrect revisions
Incorrect TOC page number in RTF to DOCX conversion
Other most recent bug fixes are also included in this release
Newly added documentation pages and articles
Some new tips and articles have now been added into Aspose.Words for .NET documentation that may guide users briefly how to use Aspose.Words for performing different tasks like the followings.
Working with Table-Row Data Bands
Working with Table-Row Conditional Blocks
Overview: Aspose.Words
Aspose.Words is a word processing component that enables .NET, Java & Android applications to read, write and modify Word documents without using Microsoft Word. Other useful features include document creation, content and formatting manipulation, mail merge abilities, reporting features, TOC updated/rebuilt, Embedded OOXML, Footnotes rendering and support of DOCX, DOC, WordprocessingML, HTML, XHTML, TXT and PDF formats (requires Aspose.Pdf). It supports both 32-bit and 64-bit operating systems. You can even use Aspose.Words for .NET to build applications with Mono.
More about Aspose.Words
Homepage Java Word Library
Download Aspose.Words for Java
#Show Hide Chart Axis#Single-Column Table Data Bands#Conditional Blocks for LINQ Reporting Engine#Preserve Meta-Characters During Replacement#Java Word Processing#DOCX to HTML conversion
0 notes
Text
Why Kotlin language, Android? Why did Google choose Kotlin ?
Why Kotlin language?
If today I was asked what is one of the characteristics that distinguishes the development of Android applications from the rest of the fields, I would not hesitate to answer that the possibility of executing the same application on devices with a different hardware in a native way is one of them; but … how is this possible? And today I would like to start my series of Kotlin language articles, explaining the language and the benefits of it.
At this point no one is surprised to see the same web application running on any device and on any platform (Android, iOS, Windows, MacOS …), we all know that these applications are slower and more unstable than any native application; but in exchange we only have to develop one application for all platforms. A similar problem would arise when talking about the number of different devices on which Android works right now; and I say would if it wasn’t because of Java. The power of Java and the fact that it is used in billions of devices today, it’s ability to work on any device regardless of its hardware and software, as long as it has an interpreter of the pseudo-compiled code generated by the Java compiler (The official Java interpreter is the Java Virtual Machine, although on Android Dalvik was used in the first versions and ART today).
Does this mean that Java is the solution to all evils? Unfortunately, nothing is further from the truth … Although Java solves the problem of interoperability between devices, it opens a new range of headaches that we would like to be able to remove from the equation, some of them *:
* Note: Many of these problems, although resolved in Java 8 and 9, are not available in the Android SDK below API 24, which makes them practically unusable)
There is no native support for optionals (although we do have it for immutable collections). Although there is the Optional <T> class, its use implies the generation of a large amount of boilerplate code, which we could save if the support for the options was built within the language itself and not as an extension of it.
There is no native support for functional programming: In Java there is the Stream Api (Once again it only has support in Android starting from API 24), but its integration in the language is similar to the one of Optional, it exists poorly in the objects associated with primitive types (IntStream, DoubleStream …), and through a Stream class <T> for all other objects.
Support for anonymous functions (Lambdas). Although Java 8 incorporates support for Lambda functions, these are not first-class citizens; this means that, although we can use lambdas to implement anonymously interfaces with a single method, Java does not support passing functions as arguments to a method. In addition, the lack of type inference makes the statement of Lambdas quite uncomfortable, especially in the attempt to simulate functions such as composition of functions or currying; lack of support for them in the language.
Type nullability: Although this can be included within the section referring to the optional, the dimension of this problem deserves a special mention. How many Java programmers didn’t fill their code with if (foo! = Null) to try to fight the dreaded NullPointerException? (Actually, it’s creator apologised for what he calls a “billion-dollar mistake”) And how many of those check ups are more than patches to avoid a crash in our application?
Binding of manual views: Although this problem is specific to Android as a Platform, and not Java as a language, it is also worth pointing out the amount of boilerplate code needed to obtain a reference to an Android view. Although we have managed to eliminate the hated findViewById (int id) thanks to dataBinding, we still have to store a reference to that binding.
It is more general, but not less important, Java is a very verbose language, it requires writing a large amount of code for any operation, as well as generating a large number of files (one per class). The first problem can lead us to a code more expensive to maintain and more prone to errors. The second is a problem of class proliferation.
Why Kotlin language breaks with all this?
It is for all these reasons that, today, Java is considered as a language that, at least in Android development, does not evolve at the speed that the industry does.
As time passes, the need to have a language with real and native support for everything mentioned above becomes more imperative, as well as maintaining the main feature of Android exposed at the beginning of this article, its ability, writing and compiling a single application, make it work on any device and version of it. In this direction many possibilities have been explored, some of them being the use of Swift or Scala, although none has been very promising.
All this changed with the appearance of Kotlin language. Kotlin is a language designed and developed by Jetbrains, focused on being a modern language, in constant evolution and, above all, that can be executed on the JVM. This makes it a perfect candidate to be used on Android.
To begin to demonstrate it, we can list down all the cons we face with Java and how Kotlin language acts in front of them:
Optionals. They’re built in inside Kotlin, all you have to do is declare the type of a variable ending in a question mark ? so it becomes an optional type. Kotlin language also provides the possibility of safely unwrapping those optionals listener?.onSuccess() without checking if there’s a value for this optional, and also provides the Elvis Operator.
Functional programming: In Kotlin we find native support to work with collections and datasets like Streams. We can directly call .flatMap {} in a collection, as well as .filter {}, .map {}, and many more. The inference of types makes the use of Lambdas especially manageable.
Lambdas and high order functions: The previous point is completed with the fact that in Kotlin language, the functions are first class citizens. We can define functions that receive other functions as parameters. An example of this is the definition of the map function itself:
inline fun <T, R> Iterable.map(transform: (T) -> R): List (source)
Although at first sight this code may seem a bit chaotic, the part that interests us is
transform: (T) -> R
This means, the map function has a parameter called transform, which is itself a function that has an input parameter of type T and returns an object of type R.
Thanks to this native support for lambdas, in Kotlin language we can use the map function such that:
collection.map { item -> aTransformation(item) }
This code snippet will return a collection of elements of the type returned by aTransformation.
Type nullability: In Kotlin language, since there is an integrated support in the language for optionals, we should have the minimum possible number of nullables in our code. But even so, if it exists, Kotlin offers us tools to deal with them easier than in Java. For example we have the operator safe call (?) to avoid NullPointerException when accessing an optional, or with the operator safe cast to protect us in case of wanting to perform a casting. The compiler of Kotlin, in addition, forces to control the types that could have null value, and even introduces runtime checks in case of compatibility with Java code.
Binding of views: This being a specific Android problem, Jetbrains offers us Kotlin Android Extensions; an official support library to simplify this problem (and some other) through a gradle plugin.
Verbosity of language:
Java
Public interface Listener { void success(int result); void error(Exception ex); } Public void someMethod(Listener listener) { int rand = new Random().nextInt(); If (listener != null) { if (rand <= 0) { listener.onError(new ValueNotSupportedException()); } else { listener.success(rand); } } Public void fun(Type1 param1) { param1.someMethod(new Listener() { @Override public void success(int result) { println(“Success” + result); } @Override public void error(Exception ex) { ex.printStackTrace(); } } }
Kotlin
fun someMethod(success: (Int) -> Unit, error: (Exception) -> Unit) { val rand = Random().nextInt() if (rand <= 0) { error(ValueNotSupportedException()) else { success(rand) } }
Or even, using expressions:
fun someMethod(success: (Int) -> Unit, error: (Exception) -> Unit) { val rand = Random().nextInt() if (rand <= 0) error(ValueNotSupportedException()) else success(rand) }
It is up to the reader to decide which of the two snippets is easier to write and interpret.
All the discussed above, along with another large number of features that did not fit in this article or that were not the ones that really matter to us shows us that Kotlin language seems the most promising bet for the next few years in the world of mobile development. In my next articles, we will study more in detail what benefits we get by using Kotlin in Android development and its impact on the industry.
And if you are interested in mobile development, I highly recommend you to subscribe to our monthly newsletter by clicking here.
If you found this article about Kotlin language interesting, you might like…
iOS Objective-C app: sucessful case study
Mobile app development trends of the year
Banco Falabella wearable case study
Mobile development projects
Viper architecture advantages for iOS apps
MVP pattern in iOS
The post Why Kotlin language, Android? Why did Google choose Kotlin ? appeared first on Apiumhub.
Why Kotlin language, Android? Why did Google choose Kotlin ? published first on http://ift.tt/2w7iA1y
0 notes
Text
What is AndroidX and Why It is Important to Migrate to AndroidX
ADMIN IN ANDROID, ANDROID APPS BLOG, ANDROIDX, APPLICATION DEVELOPMENT, APPS
If you're unfamiliar with the phrase, AndroidX is a brand-new open-source initiative that Google is introducing to package libraries with Jetpack. In short, Google decided to start cleaning up their act and utilise a new approach along with new library names because the old method of managing libraries was becoming difficult.
AndroidX Overview
The Android team leverages the new open-source project called AndroidX to create, test, and distribute libraries for Jetpack.
A significant improvement over the original Android Support Library is AndroidX. Similar to the Support Library, AndroidX is developed separately from the Android OS and offers backward compatibility between different Android releases. By offering feature parity and additional libraries, AndroidX completely replaces the Support Library. Additionally, AndroidX has the following capabilities:
All AndroidX packages are located in a single namespace that begins with the letters android x. The comparable AndroidX.* packages have been mapped to the Support Library packages. See the Package Refactoring page for a complete mapping of all the old classes and build objects to the new ones.
AndroidX packages, in contrast to the Support Library, are independently updated and maintained. Beginning with version 1.0.0, the AndroidX packages strictly adhere to semantic versioning. AndroidX libraries in your app can be freely updated.
The AndroidX library will be where all future Support Library work takes place. This entails updating the original Support Library objects and adding fresh Jetpack elements.
Why migrate to AndroidX?
The support library is no longer being maintained and is now at version 28.0.0. Therefore, moving to AndroidX is crucial and necessary if we want bug fixes or new features that would previously have been included in the Support Library. The AndroidX namespace will be used for the release of all new Jetpack libraries.
There are a lot of benefits to switching from Android Support Library to AndroidX. The most recent version information is below:
Android 10 (API level 29)*
Until August 3, 2020, new apps must comply.
required for app updates on November 2, 2020
Better package management:
You get better consistent naming, more regular releases, and independent yet standardised versioning with AndroidX. Other libraries, such as Google Play services, Firebase, Butterknife, Databinding Mockito, and SQL Delight, have switched to using the AndroidX namespace libraries.
Migration is mandatory:
The AndroidX namespace will be used for the release of all new Jetpack libraries. You must switch to the AndroidX namespace in order to utilise features like Jetpack Compose or CameraX, for instance.
Hassle-free App Architecture:
If you want to create an app using Google's Single-Activity Architecture recommendation, you must use the Jetpack Navigation Component.
Google recommended arch:
MVVM pattern combined with Repos and Arch Components. To make the code base scalable, maintainable, and to get better CC, it is inevitable to create big scale programmes using a modular architecture to isolate via modules. Writing exams is made simple.
Conclusion:
There is no getting around this migration because the support library artefacts are being deprecated and all future development is moving to AndroidX. XcelTec is the best option if you want to transfer an existing Android app to Android X. We are a software company that has long offered the top mobile and web solutions.
Little about XcelTec:
To fulfil its purpose of "Delivering Excellence in Technology," XcelTec consistently transforms customer needs into innovative and worthwhile solutions.
We are a tech company that offers business solutions for offshore software development and software outsourcing. Microsoft technology, E-commerce, M-commerce, mobile development, and open source technology are all areas where XcelTec thrives.
By establishing a foundation of work ethics and continuous progress, we uphold honesty, the degree of fulfilment, and dependability with our deeply valued consumers. We can confidently and with great pride say that we are moving in the direction of our mission.
At our company, we are well aware that consumers are looking for employees that can fully understand their problems and logically provide clever digital solutions. XcelTec is aware that our customer wants to make things simple for everyone, whether it be their end customers, vendors, associates, or workers.
Sources:
Migrating to AndroidX: The time is right! Let’s summarize it!
AndroidX Support in React Native Apps
Visit to explore more on What is AndroidX and Why It is Important to Migrate to AndroidX
Get in touch with us for more!
Contact us on:- +91 987 979 9459 | +1 919 400 9200
Email us at:- [email protected]
#what is androidx#Androidx in android#androidx migration#androidx support library#androidx migration developer#androidx migration react native#androidx migration flutter
0 notes
Text
ButterKnife を捨てて Data Binding を使えるのか?
概要
先日、会社の Android アプリの師匠に「ButterKnife と Data Binding はどちらが良いですか?」と伺ったところ、「Data Binding です」との即答を頂いたので、試しに採用してみる。
それって何するものなの?
まず、Android ではレイアウトをXMLで記述し、Activity という Java のクラスでそれらに定義した View を find して利用する。 この find の記述が面倒くさいので、自動で関連付けてくれないかという要望に応えてくれるのが ButterKnife と Data Binding である。 View 専用の Dependency Injection だという話をどこかで見たような気がするが詳しくは知らない。
ButterKnife が先発で、 Data Binding が後から Google によって提供されるようになった。 なので ButterKnife を Data Binding に置き換える、という話が多い。
導入
app/build.gradle に3行追記するだけで有効になる。
app/build.gradle android { //... dataBinding { enabled = true }
ButterKnife からの置き換え
ButterKnife を利用しているコードを置き換えていく。
layout.xml の修正
次に、対象の layout.xml に対し、全体を <layout> というタグで囲う。ここでもうこれまでの Layout ファイルと互換性がなくなるので、 気持ち悪さを禁じえなかった。もうちょっとましにできなかったのかなと思う。
layoutタグで囲う <?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout ... </layout>
コードの修正
すると、Binding クラスが自動生成される。クラス名は layout.xml の名前に応じて変わり、例えば acitivy_main.xml という名前だった場合は、 ActivityMainBinding という名前になる。Android のレイアウトファイル名は activity_具象名.xml で付けることが多いので、 それに合わせてほしかった気持ちが強い。
Binding オブジェクト は DataBindingUtil#setContentView で取得する。
Bindingオブジェクトの取得public class SettingsActivity extends AppCompatActicity { /** Binding instance. */ private ActivitySettingsBinding binding; @Override public void onCreate(Bundle b) { super.onCreate(b); setContentView(R.layout.activity_settings); binding = DataBindingUtil.setContentView(this, R.layout.activity_settings);
id を振った View のオブジェクトは Binding オブジェクトのフィールドとしてすべて保持されている。 id の snake_case を camelCase にした名前が自動で付けられる。 これによりインスタンスのインジェクションコードが不要になるので、コードは ButterKnife 使用時よりもすっきりする(ように思える)。
View Action の実装
onClick 等の挙動を実装するのは ButterKnife よりも手間がかかる感じで、Layout ファイルに Activity の依存を書かなくてはいけない。 デザインを記述する Layout ファイルにロジック関連の記述を入れ込むことに違和感や嫌悪感を感じるので、ここを我慢するか、 あるいは使わないで純粋に View のインジェクションにのみ用いるか、要はやりようである。 Activity のコードが簡潔になるだけでも利点は十分と言える。
クリックアクションを指定するためだけに Activity の依存を追記 <?xml version="1.0" encoding="utf-8"?> <layout> <data> <variable name="activity" type="jp.toastkid.calendar.settings.SettingsActivity" /> </data> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/settings_color" android:layout_width="match_parent" android:layout_height="@dimen/settings_item_height" android:onClick="@{activity.color}" >
そして Activity のコードからインスタンスを渡してやる。
Activity インスタンスを渡すsetContentView(R.layout.activity_settings); binding = Data BindingUtil.setContentView(this, R.layout.activity_settings); binding.setActivity(this);
ついでに、 ButterKnife と違って、 android:onClick で指定するメソッドは OnClickListener.onClick とシグネチャを合わせなければならない。
ButterKnifeの頃@OnClick(R.id.settings_color) public void color() { //... }
と書けていた箇所は、 Data Binding では必ず View を引数に取るようにしなければならない。
Data Bindingでの変更public void color(final View view) { //... }
うーん、Retrolambda 入れているなら Lambda 式で書いてしまった方がコードとしてはわかりやすくなるのではないか?
include での問題
include する Layout ファイルでも同じように <layout> タグで囲めば Binding オブジェクトが生成されていく。 あまり深い構造にし過ぎると、ひたすら . で連なって見づらいコードになるので考え物ではある。
感想
今日軽く使った感じでは、ButterKnife で満足できているなら、わざわざ乗り換えるほどのものでもないのでは��いう見解である。 Binding オブジェクトにすべての View がぶら下がる形になるので.が2つ続くコードを書くことになるし、 自動で付けられる名前を強制させられるので採用している命名規則によっては長ったらしい記述を強いられることになる。 Activity と Layout が密結合する欠陥も見逃し難い。
ButterKnife は Jake Wharton 氏が書いたライブラリだし、現在もメンテナンスされているので、ButterKnife で満足できているなら別に急いで乗り換える必要はまったくない。 Data Binding でしかできないことというのも、そんなにはないようだ。なお、置き換えによってリリースビルドのAPKサイズは2KBだけ小さくなったが、 影響があったのか全然わからない。
まあ、全然使い方を知らないよりはましなので、この取り組みは無駄ではなかった。もうちょっと使ってみる。
どうでもいいこと
私が ButterKnife に執着するのは、下記の理由からだ。
楽しかった開発プロジェクトの思い出と共にあるライブラリだから
layout と Activity の距離を従来通り保ちつつ書き方だけを便利にできるから
Jake Wharton 氏のライブラリだから
トーストに Butter Knife は欠かせない道具(バターを塗るための切れないナイフ)だから
はい、御察しの通り3点目を書きたかっただけである。
References
Data Binding through Plaid……ベトナムで聞いてきたセッションの資料
Butter Knife、今までありがとう。 Data Binding、これからよろしく。……こちらの記事でも ButterKnife を使ったコードを Data Binding に置き換えていた。
0 notes
Text
ModelViewBinding
This library handles Orientation change for databinding.
from The Android Arsenal http://ift.tt/2uo0KmF
0 notes